<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="icon" class="icon">
    <ul class="icon">
        <li class="weixin">weixin</li>
        <li class="weibo">weibo</li>
    </ul>
    <div class="">
        <img class="show" src="img/weixin.png" alt="weixin">
        <img src="img/weibo.png" alt="weibo">
        <span class="arrow"><em>---->>>></em></span>
    </div>
</div>
<script>
    let throttle = function () {
        let isClear = arguments[0], fn;

        // 第一个参数表示是否清楚计时器
        if (typeof isClear === 'boolean') {
            // 第二个参数则为函数
            fn = arguments[1];
            fn.__trottleID && clearTimeout(fn.__trottleID);
        } else {
            // 第一个参数为函数
            fn = isClear;
            // 第二个参数为函数执行时候的参数
            let param = arguments[1];
            let p = Object.assign({
                context: null,
                args: [],
                time: 300
            }, param);
            arguments.callee(true, fn);
            fn.__trottleID = setTimeout(function () {
                fn.apply(p.context, p.args)
            }, p.time)
        }
    };

    /**
     * 优化鼠标华东元素而展现浮层的交互
     * 当鼠标不小心移出了浮层， 浮层立马消失。 有的时候无意间移入元素上面会出现浮层展现。
     * 这两种体验模式可以利用节流模式优化
     */
    // 先用外观模式封装获取元素方法
    function $(id) {
        return document.getElementById(id);
    }

    function $tag(tag, container = document) {
        return container.getElementsByTagName(tag);
    }

    // 浮层类
    class Layer {
        constructor(id) {
            this.container = $(id);
            // 获取容器中的浮层容器
            this.layer = $tag('div', this.container)[0];
            // 获取icon容器
            this.lis = $tag('li', this.container);
            // 获取二维码图片
            this.imgs = $tag('img', this.container);
            // 绑定事件
            this.bindEvent();
        }

        // 绑定交互事件
        bindEvent() {
            // 添加节流器， 实际上就是让交互延迟出发而已

            // 隐藏浮层
            let hideLayer = () => this.layer.className = '';

            //显示浮层
            let showLayer = () => this.layer.className = 'show';

            // 鼠标光标移入事件
            this.on(this.container, 'mouseenter', function () {
                // 清楚隐藏浮层方法计时器
                throttle(true, hideLayer);
                // 延迟显示浮层方法
                throttle(showLayer);
            }).on(this.container, 'mouseleave', function () {
                throttle(hideLayer);
                throttle(true, showLayer);
            });

            // 绑定icon 事件
            for (let i = 0; i < this.lis.length; i++) {
                this.lis[i].index = i;
                this.on(this.lis[i], 'mouseenter', function () {
                    let index = this.index;
                    for (let i = 0; i < this.imgs.length; i++) {
                        this.imgs[i].className = '';
                    }
                    this.imgs[index].className = 'show';
                    this.layer.style.left = -22 + 60 * index + 'px';
                })
            }
        }

        // 绑定方法
        on(ele, type, fn) {
            ele.addEventListener ? ele.addEventListener(type, fn, false) : ele.attachEvent('on' + type, fn);
            return this;
        }
    }
</script>
</body>
</html>